package com.passion.components;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.passion.common.context.SpringContextUtil;
import com.passion.service.SysUriService;
import com.passion.service.impl.SysUriServiceImpl;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 类描述：扫描系统web层对外暴露的端点，存到数据库中当作看板
 *
 * @author ZhuYin
 * @since 2024年11月29日
 */
@Slf4j
@Component
public class EndpointScanner implements CommandLineRunner {

    @Override
    public void run(String... args) {
        RequestMappingHandlerMapping handlerMapping = SpringContextUtil.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();

        Map<String, List<String>> endpoints = Maps.newHashMap();

        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
            RequestMappingInfo info = entry.getKey();
            HandlerMethod handlerMethod = entry.getValue();

            Set<String> patterns = info.getPatternsCondition().getPatterns();
            RequestMethod[] methods = info.getMethodsCondition().getMethods().toArray(new RequestMethod[0]);

            for (String pattern : patterns) {
                for (RequestMethod method : methods) {
                    String key = method.name() + " " + pattern;
                    if (!endpoints.containsKey(key)) {
                        endpoints.put(key, new ArrayList<>());
                    }
                    endpoints.get(key).add(handlerMethod.getMethod().toString());
                }
            }
        }
        SysUriService sysUriService = SpringContextUtil.getBean(SysUriService.class);
        // 打印所有端点
        StringBuilder sb = new StringBuilder();
        sb.append("\n👉👇👇👇👇👇👇👇👇👇👇👇👇👇👇 System Endpoints 👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇");
        Set<String> uris = Sets.newHashSet();
        for (Map.Entry<String, List<String>> entry : endpoints.entrySet()) {
            String key = entry.getKey();
            if (StringUtils.isNotBlank(key)) {
                String[] split = key.split(" ");
                String uri = split[1];
                if (!SysUriServiceImpl.IGNORE_URI_SET.contains(uri)) {
                    sb.append("\n👉\t  Endpoint => ").append(key);
                    uris.add(uri);
                }
            }
        }
        sb.append("\n👉\n👉\t  Total count: ").append(uris.size());
        sb.append("\n👉👆👆👆👆👆👆👆👆👆👆👆👆👆👆 System Endpoints 👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆");
        log.info(sb.toString());
        sysUriService.saveUris(uris);
    }
}